package com.ssy.lingxi.member.merchant.entity;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonManagedReference;

import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Set;

/**
 * 会员信息
 * @author 万宁
 * @version 2.0.0
 * @date 2020-06-03
 */
@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
@Entity
@Table(schema = "public", name = "ms_mc_member", indexes = {@Index(name = "ms_mc_member_account_idx", columnList = "account"), @Index(name = "ms_mc_member_name_idx", columnList = "name"), @Index(name = "ms_mc_member_phone_idx", columnList = "phone"), @Index(name = "ms_mc_member_register_time_idx", columnList = "registerTime"), @Index(name = "ms_mc_member_source_idx", columnList = "source")})
public class MemberDO implements Serializable {
    private static final long serialVersionUID = -4993427791681123026L;

    /**
     * 会员id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_seq")
    @SequenceGenerator(sequenceName = "ms_mc_member_seq", name = "member_seq", allocationSize = 1)
    private Long id;

    /**
     * 注册申请时间
     */
    @Column(columnDefinition = "timestamp")
    private LocalDateTime registerTime;

    /**
     * 注册来源， 定义在MemberRegisterSourceEnum
     */
    @Column(columnDefinition = "int2")
    private Integer source;

    /**
     * 账号
     */
    @Column(columnDefinition = "varchar(50)", nullable = false)
    private String account;

    /**
     * 国家代码（手机号码前缀）
     */
    @Column(columnDefinition = "varchar(20)")
    private String countryCode;

    /**
     * 会员名称
     */
    @Column(columnDefinition = "varchar(200)")
    private String name;

    /**
     * 手机号码
     */
    @Column(columnDefinition = "varchar(20)", nullable = false)
    private String phone;

    /**
     * 密码
     */
    @Column(columnDefinition = "varchar(50)", nullable = false)
    private String password;

    /**
     * 支付密码
     */
    @Column(columnDefinition = "varchar(50)")
    private String payPassword;

    /**
     * 邮箱
     */
    @Column(columnDefinition = "varchar(100)", nullable = false)
    private String email;

    /**
     * 会员头像
     */
    @Column(columnDefinition = "varchar(400)")
    private String logo;

    /**
     * 一对一双向关联会员权限
     */
    @JsonManagedReference
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.DETACH}, fetch = FetchType.LAZY)
    @JoinColumn(name = "member_auth_id", referencedColumnName = "id")
    private MemberAuthDO memberAuth;

    /**
     * 多对多双向关联会员角色
     */
    @JsonManagedReference
    @ManyToMany(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
    @JoinTable(name = "ms_mc_member_role_relation", joinColumns = {@JoinColumn(name = "member_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")})
    private Set<RoleDO> roles;

    /**
     * 一对多双向关联注册资料
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "member", cascade = {CascadeType.DETACH, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<MemberRegisterDetailDO> registerDetails;

    /**
     * 一对多双向关联下属的用户
     */
    @JsonBackReference
    @OneToMany(mappedBy = "member", cascade = {CascadeType.DETACH, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<MemberUserDO> users;

    /**
     * 一对多双向关联自定义的组织机构
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "member", cascade = {CascadeType.DETACH, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<MemberOrganizationDO> orgs;

    /**
     * 一对多双向关联会员自定义的角色
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "member", cascade = {CascadeType.DETACH, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<MemberRoleDO> memberRoles;

    /**
     * 一对多双向关联会员门店
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "member", cascade = {CascadeType.DETACH, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<MemberStoreDO> memberStores;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public LocalDateTime getRegisterTime() {
        return registerTime;
    }

    public void setRegisterTime(LocalDateTime registerTime) {
        this.registerTime = registerTime;
    }

    public Integer getSource() {
        return source;
    }

    public void setSource(Integer source) {
        this.source = source;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getCountryCode() {
        return countryCode;
    }

    public void setCountryCode(String countryCode) {
        this.countryCode = countryCode;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPayPassword() {
        return payPassword;
    }

    public void setPayPassword(String payPassword) {
        this.payPassword = payPassword;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getLogo() {
        return logo;
    }

    public void setLogo(String logo) {
        this.logo = logo;
    }

    public MemberAuthDO getMemberAuth() {
        return memberAuth;
    }

    public void setMemberAuth(MemberAuthDO memberAuth) {
        this.memberAuth = memberAuth;
    }

    public Set<RoleDO> getRoles() {
        return roles;
    }

    public void setRoles(Set<RoleDO> roles) {
        this.roles = roles;
    }

    public Set<MemberRegisterDetailDO> getRegisterDetails() {
        return registerDetails;
    }

    public void setRegisterDetails(Set<MemberRegisterDetailDO> registerDetails) {
        this.registerDetails = registerDetails;
    }

    public Set<MemberUserDO> getUsers() {
        return users;
    }

    public void setUsers(Set<MemberUserDO> users) {
        this.users = users;
    }

    public Set<MemberOrganizationDO> getOrgs() {
        return orgs;
    }

    public void setOrgs(Set<MemberOrganizationDO> orgs) {
        this.orgs = orgs;
    }

    public Set<MemberRoleDO> getMemberRoles() {
        return memberRoles;
    }

    public void setMemberRoles(Set<MemberRoleDO> memberRoles) {
        this.memberRoles = memberRoles;
    }

    public Set<MemberStoreDO> getMemberStores() {
        return memberStores;
    }

    public void setMemberStores(Set<MemberStoreDO> memberStores) {
        this.memberStores = memberStores;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        MemberDO memberDO = (MemberDO) o;
        return id.equals(memberDO.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}
